﻿#If WINDOWS Then
Imports System.Collections.Specialized
Imports System.Text

Namespace Global.System.Management

#Region "WMIPath"
    Public Enum WMIPath
        Win32_Processor
        Win32_PhysicalMemory
        Win32_Keyboard
        Win32_PointingDevice
        Win32_FloppyDrive
        Win32_DiskDrive
        Win32_CDROMDrive
        Win32_BaseBoard
        Win32_BIOS
        Win32_ParallelPort
        Win32_SerialPort
        Win32_SerialPortConfiguration
        Win32_SoundDevice
        Win32_SystemSlot
        Win32_USBController
        Win32_NetworkAdapter
        Win32_NetworkAdapterConfiguration
        Win32_Printer
        Win32_PrinterConfiguration
        Win32_PrintJob
        Win32_TCPIPPrinterPort
        Win32_POTSModem
        Win32_POTSModemToSerialPort
        Win32_DesktopMonitor
        Win32_DisplayConfiguration
        Win32_DisplayControllerConfiguration
        Win32_VideoController
        Win32_VideoSettings
        Win32_TimeZone
        Win32_SystemDriver
        Win32_DiskPartition
        Win32_LogicalDisk
        Win32_LogicalDiskToPartition
        Win32_LogicalMemoryConfiguration
        Win32_PageFile
        Win32_PageFileSetting
        Win32_BootConfiguration
        Win32_ComputerSystem
        Win32_OperatingSystem
        Win32_StartupCommand
        Win32_Service
        Win32_Group
        Win32_GroupUser
        Win32_UserAccount
        Win32_Process
        Win32_Thread
        Win32_Share
        Win32_NetworkClient
        Win32_NetworkProtocol
    End Enum
#End Region

    ''' <summary> 
    ''' Fetch the system info.
    ''' </summary>
    ''' <example>
    ''' <code> 
    ''' Dim w As New WMI(WMIPath.Win32_NetworkAdapterConfiguration) 
    ''' For i = 0 To w.Count
    '''     If CBool(w(i, "IPEnable")) Then
    '''         Console.WriteLine("Caption:{0}", w(i, "Caption"))
    '''         Console.WriteLine("MAC Address:{0}", w(i, "MACAddress")) 
    '''     End If
    ''' Next
    ''' </code> 
    ''' </example> 
    Public NotInheritable Class WMI
        Private mocs As ArrayList
        Private names As StringDictionary

        Public ReadOnly Property Count() As Integer
            Get
                Return mocs.Count
            End Get
        End Property

        Default Public ReadOnly Property Item(index As Integer, propertyName As String) As Object
            Get
                Try
                    Dim trueName As String = names(propertyName.Trim())
                    Dim h As Hashtable = DirectCast(mocs(index), Hashtable)
                    Return h(trueName)
                Catch
                    Return Nothing
                End Try
            End Get
        End Property

        Public Sub New(path As String)
            names = New StringDictionary()
            mocs = New ArrayList()

            Try
                Dim cimobject As New ManagementClass(path)
                Dim moc As ManagementObjectCollection = cimobject.GetInstances()

                Dim ok As Boolean = False
                For Each mo As ManagementObject In moc
                    Dim o As New Hashtable()
                    mocs.Add(o)

                    For Each p As PropertyData In mo.Properties
                        o.Add(p.Name, p.Value)
                        If Not ok Then
                            names.Add(p.Name, p.Name)
                        End If
                    Next

                    ok = True
                    mo.Dispose()
                Next
                moc.Dispose()
            Catch e As Exception
                Throw New Exception(e.Message)
            End Try
        End Sub

        Public Sub New(path As WMIPath)
            Me.New(path.ToString())
        End Sub

        Public Function PropertyNames(index As Integer) As String()
            Try
                Dim h As Hashtable = DirectCast(mocs(index), Hashtable)
                Dim result As String() = New String(h.Keys.Count - 1) {}

                h.Keys.CopyTo(result, 0)

                Array.Sort(result)
                Return result
            Catch
                Return Nothing
            End Try
        End Function

        Public Overrides Function ToString() As String
            Try
                Dim result As New StringBuilder(1000)

                For i As Integer = 0 To Count - 1
                    Dim j As Integer = 0
                    For Each s As String In PropertyNames(i)
                        result.Append(String.Format("{0}:{1}={2}" & vbLf, System.Threading.Interlocked.Increment(j), s, Me(i, s)))

                        If TypeOf Me(i, s) Is Array Then
                            Dim v1 As Array = TryCast(Me(i, s), Array)
                            For x As Integer = 0 To v1.Length - 1
                                result.Append(vbTab & v1.GetValue(x) & vbLf)
                            Next
                        End If
                    Next
                    result.Append("======WMI=======" & vbLf)
                Next

                Return result.ToString()
            Catch
                Return String.Empty
            End Try
        End Function

        Public Shared Function GetHardwareInfoString() As String
            On Error Resume Next

            Dim sb As New StringBuilder()
            'Try
            Dim w_Processor As New WMI(WMIPath.Win32_Processor)
            Dim w_PhysicalMemory As New WMI(WMIPath.Win32_PhysicalMemory)
            Dim w_DisplayConfiguration As New WMI(WMIPath.Win32_DisplayConfiguration)
            Dim w_DisplayControllerConfiguration As New WMI(WMIPath.Win32_DisplayControllerConfiguration)
            Dim w_VideoController As New WMI(WMIPath.Win32_VideoController)
            Dim w_VideoSettings As New WMI(WMIPath.Win32_VideoSettings)
            Dim w_OperatingSystem As New WMI(WMIPath.Win32_OperatingSystem)

            sb.AppendLine(w_Processor.ToString())
            sb.AppendLine(w_PhysicalMemory.ToString())
            sb.AppendLine(w_DisplayConfiguration.ToString())
            sb.AppendLine(w_DisplayControllerConfiguration.ToString())
            sb.AppendLine(w_VideoController.ToString())
            sb.AppendLine(w_VideoSettings.ToString())
            sb.AppendLine(w_OperatingSystem.ToString())
            'Catch ex As Exception
            '    Trace.WriteLine(ex.Message & vbCrLf & ex.StackTrace.ToString())
            'End Try
            Return sb.ToString()
        End Function

    End Class

End Namespace

#End If